package com.sikaryofficial.common.core.annotation;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;
/**
 * @author : qinjinyuan
 * @desc : localDateTime format
 * @date : 2023/12/06 20:08
 */
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class LocalDateTimeFormatSerialize extends JsonSerializer implements ContextualSerializer {

    private String pattern;

    @Override
    public void serialize(Object objValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (Objects.isNull(objValue)) {
            jsonGenerator.writeString("");
            return;
        }
        Date value = (Date) objValue;
        ZonedDateTime zonedDateTime = value.toInstant().atZone(ZoneId.systemDefault());
        String formattedDate = DateTimeFormatter.ofPattern(pattern).format(zonedDateTime);
        jsonGenerator.writeString(formattedDate);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (Objects.nonNull(beanProperty)) {
            if (Objects.equals(beanProperty.getType().getRawClass(), Date.class)) {
                LocalDateTimeFormat anno = beanProperty.getAnnotation(LocalDateTimeFormat.class);
                if (Objects.isNull(anno)) {
                    anno = beanProperty.getContextAnnotation(LocalDateTimeFormat.class);
                }
                if (Objects.nonNull(anno)) {
                    this.pattern = anno.pattern();
                    return new LocalDateTimeFormatSerialize(pattern);
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}